#include "TCP_Test.h"
#include "stm32f4xx.h"                  // Device header
#include "usart.h" 


#define DATA_BUF_SIZE 2048
#define _LOOPBACK_DEBUG_
#define KEEPALIVE_ENABLE 1
extern u8 RXBuffer[RXBUFFER_LEN];
extern u8 QR_Flag;
extern u8 QR_Len;
extern u8 Uart3RxBuf[UART3_RX_BUF_LEN];
extern u8 Uart3RxDataConut ;
extern u8 IC_Flag;
extern u8 IC_Len;

int32_t TCP_Client(uint8_t sn, uint8_t *buf, uint8_t *destip, uint16_t destport)
{
	u8 scan_cmd[9] = {0x7E, 0x00, 0x08, 0x01, 0x00, 0x02, 0x01, 0xAB, 0xCD};
	u8 i;
	int32_t ret; // return value for SOCK_ERRORs
    uint16_t size = 0, sentsize = 0;
	// Port number for TCP client (will be increased)
	static uint16_t any_port = 50000;
	// Destination (TCP Server) IP info (will be connected)
	// >> loopback_tcpc() function parameter
	// >> Ex)
    uint8_t dip[4] = {192, 168, 0, 214};
    uint16_t dport = 5000;
    getSn_DIPR(sn, dip);
    dport = getSn_DPORT(sn);

   // Socket Status Transitions
   // Check the W5500 Socket n status register (Sn_SR, The 'Sn_SR' controlled by Sn_CR command or Packet send/recv status)
   switch (getSn_SR(sn))
   {
   case SOCK_ESTABLISHED:
      if (getSn_IR(sn) & Sn_IR_CON) // Socket n interrupt register mask; TCP CON interrupt = connection with peer is successful
      {
#if KEEPALIVE_ENABLE == 1
         // We need to send a packet of data to activate keepalive
         ret = send(sn, (uint8_t *)"", 1); // Data send process
         if (ret < 0)                      // Send Error occurred (sent data length < 0)
         {
            close(sn); // socket close
            return ret;
         }
#endif
         printf("%d:Connected to - %d.%d.%d.%d : %d\r\n", sn, destip[0], destip[1], destip[2], destip[3], destport);
         setSn_IR(sn, Sn_IR_CON); // (Reset to zero by setting it to one.)this interrupt should be write the bit cleared to '1'
      }

      // Data Transaction Parts; Handle the [data receive and send] process
      if ((size = getSn_RX_RSR(sn)) > 0) // Sn_RX_RSR: Socket n Received Size Register, Receiving data length
      {
         if (size > DATA_BUF_SIZE)
            size = DATA_BUF_SIZE;   // Avoid array overflow
         ret = recv(sn, buf, size); // Data Receive process (H/W Rx socket buffer -> User's buffer)
         buf[size] = 0x00;
         printf("rece from %d.%d.%d.%d:%d data:%s\r\n", dip[0], dip[1], dip[2], dip[3], dport, buf);
         if (ret <= 0)
         return ret; // If the received data length <= 0, receive failed and process end
         size = (uint16_t)ret;
         sentsize = 0;

		 // test send QR_ScanCmd 
		 if(buf[0] == 's' && buf[1] == 'c')
		 {
			for (u8 i = 0; i < 9; i++)
			{
				USART_SendData(USART2, scan_cmd[i]);
				while(USART_GetFlagStatus(USART2, USART_FLAG_TC) != SET);  // 等待发送完成
			}
		 }
      }
	   // Data sentsize control
	   if(QR_Flag == 1)
	   {
	      ret = send(sn, RXBuffer, QR_Len); // Data send process (User's buffer -> Destination through H/W Tx socket buffer)
	      QR_Flag = 0;
	      QR_Len = 0;
	      memset(RXBuffer,0,RXBUFFER_LEN);
	      if (ret < 0)                                     // Send Error occurred (sent data length < 0)
	      {
	         close(sn); // socket close
	         return ret;
	      }
	   }
      if(IC_Flag == 1)
      {
         ret = send(sn, Uart3RxBuf + 5, 22); // Data send process (User's buffer -> Destination through H/W Tx socket buffer)
	      IC_Flag = 0;
	      memset(RXBuffer,0,RXBUFFER_LEN);
	      if (ret < 0)                                     // Send Error occurred (sent data length < 0)
	      {
	         close(sn); // socket close
	         return ret;
	      }
      }
      break;

   case SOCK_CLOSE_WAIT:
#ifdef _LOOPBACK_DEBUG_
      printf("%d:CloseWait\r\n", sn);
#endif
      if ((ret = disconnect(sn)) != SOCK_OK)
         return ret;
#ifdef _LOOPBACK_DEBUG_
      printf("%d:Socket Closed\r\n", sn);
#endif
      break;

   case SOCK_INIT:
#ifdef _LOOPBACK_DEBUG_
      printf("%d:Try to connect to the %d.%d.%d.%d : %d\r\n", sn, destip[0], destip[1], destip[2], destip[3], destport);
#endif
      if ((ret = connect(sn, destip, destport)) != SOCK_OK)
         return ret; //	Try to TCP connect to the TCP server (destination)
      break;

   case SOCK_CLOSED:
      close(sn); 
      if ((ret = socket(sn, Sn_MR_TCP, any_port++, 0x00)) != sn)
      {
         if (any_port == 0xffff) // 端口号最大为0xffff
            any_port = 50000;
            return ret; // TCP socket open with 'any_port' port number
      }
#ifdef _LOOPBACK_DEBUG_
      printf("%d:TCP client loopback start\r\n", sn);
      printf("%d:Socket opened\r\n", sn);
#endif
      break;
   default:
      break;
   }
   return 1;
}